//
//  DbUtil.m
//  Chat
//
//  Created by 任伟 on 16/3/8.
//  Copyright © 2016年 任伟. All rights reserved.
//

#import "DbUtil.h"
#import "FMDatabase.h"

#define DATABASENAME @"tft"

@interface DbUtil()

NSString *getDataBaseFilePath(NSString *dbname);

NSString *createSelectSQL(NSString *tablename,NSArray *column_list,NSDictionary *condition_map);

NSString *createUpdateSQL(NSString *tablename, NSDictionary *value_map, NSDictionary *condition_map);

NSString *createInsertSQL(NSString *tablename,NSDictionary *value_map);

NSString *createDeleteSQL(NSString *tablename,NSDictionary *condition_map);


@end

@implementation DbUtil


+(DbUtil *)sharedDatabase
{
    static DbUtil *dbUtil = nil;
    @synchronized(self){
        if (!dbUtil) {
            dbUtil = [[[self class]alloc]init];
        }
    }
    [dbUtil.db open];
    return dbUtil;
}

-(id)init
{
    if (self=[super init]) {
        NSString *path = [self copyFile2Documents:[NSString stringWithFormat:@"%@.sqlite",DATABASENAME]];
        self.db = [FMDatabase databaseWithPath:path];
    }
    
    return self;
}

-(NSString*) copyFile2Documents:(NSString*)fileName
{
    NSFileManager*fileManager =[NSFileManager defaultManager];
    NSError*error;
    NSArray*paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    NSString*documentsDirectory =[paths objectAtIndex:0];
    
    NSString*destPath =[documentsDirectory stringByAppendingPathComponent:fileName];
    
    if(![fileManager fileExistsAtPath:destPath]){
        NSString* sourcePath =[[NSBundle mainBundle] pathForResource:DATABASENAME ofType:@"sqlite"];
        [fileManager copyItemAtPath:sourcePath toPath:destPath error:&error];
    }
    return destPath;
}


-(id)initWithQueue
{
    if (self=[super init]) {
        NSBundle *bundle = [NSBundle mainBundle];
        NSString *path = [bundle pathForResource:DATABASENAME ofType:@"sqlite"];
        dbQueue = [FMDatabaseQueue databaseQueueWithPath:path];
        [self.db open];
    }
    
    return self;
}


-(void) executeQuery:(NSString *)sql results:(NSMutableArray *)results;
{
    FMResultSet *resultSet = [self.db executeQuery:sql];
    while ([resultSet next]) {
        [results addObject:resultSet.resultDictionary];
    }
}

-(void) executeQuery:(NSString *)tablename columnlist:(NSArray *)columnlist conditionmap:(NSDictionary *)conditionmap results:(NSMutableArray *)results
{
    NSString *sql = createSelectSQL(tablename, columnlist, conditionmap);
    [self executeQuery:sql results:results];
}

-(BOOL) execUpdate:(NSString *)sql
{
    if (![self.db executeUpdate:sql]) {
        return false;
    }
    return true;
}

-(BOOL) executeUpdate:(NSString *)tablename valuemap:(NSDictionary *)value_map conditionmap:(NSDictionary *)condition_map
{
    NSString *sql = createUpdateSQL(tablename, value_map, condition_map);
    return [self execUpdate:sql];
}

-(BOOL) executeInsert:(NSString *)tablename valuemap:(NSDictionary *)value_map
{
    NSString *sql = createInsertSQL(tablename, value_map);
    
    return [self execUpdate:sql];
}

-(BOOL) executeDelete:(NSString *)tablename conditionmap:(NSDictionary *)condition_map
{
    NSString *sql = createDeleteSQL(tablename, condition_map);
    
    return [self execUpdate:sql];
}

#pragma mark - private methods


NSString *getDataBaseFilePath(NSString *dbname)
{
    return [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:dbname];
}


NSString *createSelectSQL(NSString *tablename,NSArray *column_list,NSDictionary *condition_map)
{
    if (tablename == nil) {
        return nil;
    }
    NSString *sqlString = @"select";
    
    NSString *fields = @"";
    
    if (column_list == nil || [column_list count]<1) {
        fields = @" * ";
    } else {
        for (int i = 0; i<[column_list count]; i++) {
            NSString *seperator = [fields length]<1?@" ":@",";
            fields = [[fields stringByAppendingString:seperator] stringByAppendingString:[column_list objectAtIndex:i]];
        }
        
        fields = [fields stringByAppendingString:@" "];
    }
    
    sqlString = [sqlString stringByAppendingString:fields];
    sqlString = [sqlString stringByAppendingString:@"from "];
    sqlString = [sqlString stringByAppendingString:tablename];
    
    if (condition_map == nil || [condition_map count]<1) {
        return sqlString;
    }
    sqlString = [sqlString stringByAppendingString:@" where "];
    
    NSString *conditions = @"";
    
    
    for (int j =0; j < [[condition_map allKeys] count]; j++) {
        
        NSString *key = [[condition_map allKeys] objectAtIndex:j];
        NSString *value = [condition_map objectForKey:key];
        
        NSString *seperator = [conditions length]<1?@"":@" and ";
        
        conditions = [[[[conditions stringByAppendingString:seperator] stringByAppendingString:key] stringByAppendingString:@"="] stringByAppendingString:value];
    }
    
    sqlString = [sqlString stringByAppendingString:conditions];
    
    return sqlString;
}

NSString *createUpdateSQL(NSString *tablename, NSDictionary *value_map, NSDictionary *condition_map)
{
    if (tablename == nil || value_map == nil) {
        return nil;
    }
    NSString *sqlString = @"update ";
    
    sqlString = [sqlString stringByAppendingString:tablename];
    
    sqlString = [sqlString stringByAppendingString:@" set"];
    
    NSString *updateFields = @"";
    
    for (int i = 0; i<[[value_map allKeys] count]; i++) {
        
        NSString *seperator = [updateFields length]<1?@" ":@",";
        NSString *key = [[value_map allKeys] objectAtIndex:i];
        NSString *value = [value_map objectForKey:key];
        value = [NSString stringWithFormat:@"\"%@\"",value];
        
        updateFields = [[[[updateFields stringByAppendingString:seperator] stringByAppendingString:key] stringByAppendingString:@"="] stringByAppendingString:value];
    }
    
    sqlString = [sqlString stringByAppendingString:updateFields];
    
    if (condition_map == nil || [condition_map count]<1) {
        return sqlString;
    }
    sqlString = [sqlString stringByAppendingString:@" where "];
    
    NSString *conditions = @"";
    
    for (int j =0; j < [[condition_map allKeys] count]; j++) {
        
        NSString *key = [[condition_map allKeys] objectAtIndex:j];
        NSString *value = [condition_map objectForKey:key];
        
        NSString *seperator = [conditions length]<1?@"":@" and ";
        
        conditions = [[[[conditions stringByAppendingString:seperator] stringByAppendingString:key] stringByAppendingString:@"="] stringByAppendingString:value];
    }
    
    sqlString = [sqlString stringByAppendingString:conditions];
    
    return sqlString;
}

NSString *createInsertSQL(NSString *tablename,NSDictionary *value_map)
{
    if (tablename == nil || value_map == nil) {
        return nil;
    }
    NSString *sqlString = @"insert into ";
    sqlString = [sqlString stringByAppendingString:tablename];
    sqlString = [sqlString stringByAppendingString:@" ("];
    
    NSString *keyString = @"";
    
    for (int i = 0 ; i<[[value_map allKeys] count]; i++) {
        NSString *seperator = [keyString length]<1?@"":@",";
        NSString *key = [[value_map allKeys] objectAtIndex:i];
        keyString = [[keyString stringByAppendingString:seperator] stringByAppendingString:key];
    }
    sqlString = [sqlString stringByAppendingString:keyString];
    sqlString = [sqlString stringByAppendingString:@") values ("];
    
    NSString *valueString = @"";
    for (int j = 0 ; j<[[value_map allKeys] count]; j++) {
        
        NSString *seperator = [valueString length]<1?@"\"":@",\"";
        NSString *key = [[value_map allKeys] objectAtIndex:j];
        valueString = [[valueString stringByAppendingString:seperator] stringByAppendingString:[NSString stringWithFormat:@"%@", ([value_map objectForKey:key])]];
        valueString = [valueString stringByAppendingString:@"\""];
    }
    
    sqlString = [sqlString stringByAppendingString:valueString];
    sqlString = [sqlString stringByAppendingString:@")"];
    
    return sqlString;
}

NSString *createDeleteSQL(NSString *tablename,NSDictionary *condition_map)
{
    if (tablename == nil) {
        return nil;
    }
    NSString *sqlString = @"delete from ";
    sqlString = [sqlString stringByAppendingString:tablename];
    
    if (condition_map == nil || [condition_map count]<1) {
        return sqlString;
    }
    sqlString = [sqlString stringByAppendingString:@" where "];
    
    NSString *conditions = @"";
    
    for (int j =0; j < [[condition_map allKeys] count]; j++) {
        
        NSString *key = [[condition_map allKeys] objectAtIndex:j];
        NSString *value = [condition_map objectForKey:key];
        
        NSString *seperator = [conditions length]<1?@"":@" and ";
        
        conditions = [[[[conditions stringByAppendingString:seperator] stringByAppendingString:key] stringByAppendingString:@" = "] stringByAppendingString:value];
    }
    
    sqlString = [sqlString stringByAppendingString:conditions];
    
    return sqlString;
    
}

@end
